﻿using System;
using System.Collections.Generic;
using System.Linq;
using AzurePlugin.Converter;
using EnvDTE;
using EnvDTE80;
using System.IO;
using Microsoft.VisualStudio.Project.Automation;

namespace AzurePlugin
{
    public class Director
    {
        private readonly DTE2 _application;
        private SolutionConverter _solutionConverter;
        private string _logFilePath;

        public Director(DTE2 application, ServiceProviderAdapter serviceProvider)
        {
            _application = application;

            _logFilePath = makeLogFilePath();
            ConverterLogger.Init(_logFilePath);

            _solutionConverter = new SolutionConverter((Solution2) application.DTE.Solution, serviceProvider);
        }

        public void DoBackup(string backupFolder, IEnumerable<Project> proj2conversion)
        {
            new BackupCreator(_application).DoBackup(
                    backupFolder,
                    proj2conversion);
        }

        public bool DoConversionNewProject(string projectName, IEnumerable<ProjectAdapter> proj2conversion)
        {
            _solutionConverter.CreateAzureProjectAndConvert(projectName, proj2conversion);

            return true;
        }

        public bool DoConversionExistingProject(Project project, IEnumerable<ProjectAdapter> proj2conversion)
        {
            _solutionConverter.Convert((OAProject)project, proj2conversion);

            return true;
        }

        public enum ConversionType { WebRole, WorkerRole }

        public class ProjectInfo
        {
            public ProjectAdapter ProjectAdapter { get; set; }
            public ConversionType ConversionType { get; set; }
        }

        public IEnumerable<ProjectInfo> GetProjectsForConversion()
        {
            return
                _solutionConverter.GetConvertibleWebRoleProjects().Select(
                    item => new ProjectInfo() { ProjectAdapter = item, ConversionType = ConversionType.WebRole })
                    .Union(
                        _solutionConverter.GetConvertibleWorkerRoleProjects().Select(
                            item =>
                            new ProjectInfo() { ProjectAdapter = item, ConversionType = ConversionType.WorkerRole })
                    );
        }


        internal IEnumerable<Project> GetAllProjects()
        {
            return from Project proj in _application.Solution.Projects select proj;
        }

        public IEnumerable<ProjectAdapter> GetAzureProjects()
        {
            return _solutionConverter.GetAzureProjects();
        }

        public string solutionPath
        {
            get
            {
                return Path.GetDirectoryName(_application.Solution.FullName);
            }
        }

        public bool isSolutionOpen
        {
            get
            {
                return _application.Solution.IsOpen;
            }
        }

        public string cloudProjectNameByDefault
        {
            get
            {
                const string ending = ".Azure";
                return Path.GetFileNameWithoutExtension(_application.Solution.FullName) + ending;
            }
        }

        public void showLog()
        {
            ConverterLogger.Close();
            _application.ItemOperations.OpenFile(_logFilePath);
        }

        private string makeLogFilePath()
        {
            for (var i = 1; i < Constants.OVER_9000; i++)
            {
                var fileName = string.Format(
                    "{0}.AzureConversionLog{1}.txt",
                    Path.GetFileNameWithoutExtension(_application.Solution.FullName),
                    i == 1 ? string.Empty : i.ToString());

                var filePath = Path.Combine(solutionPath, fileName);

                if (!File.Exists(filePath))
                    return filePath;
            }

            throw new ArgumentOutOfRangeException(String.Format("Too many old conversion logs in '{0}'", solutionPath));
        }

        internal bool doesProjectExist(string projectName)
        {
            return (from Project project in _application.Solution.Projects select project)
                .Any(p => p.Name == projectName);
        }
    }
}
